
#pragma once

#include <boost/cstdint.hpp>
#include <boost/asio.hpp>

#include <cstdio>
#include <cstdlib>
#include <cstring>

namespace ConnectionBroker
{
   class TcpMessage
   {
   public:
      enum { header_minus_ctrl_length = sizeof(uint32_t) };
      enum { channel_length = sizeof(uint32_t) };
      enum { header_length = header_minus_ctrl_length + channel_length };

      TcpMessage();
      TcpMessage(const TcpMessage& other);
      ~TcpMessage();

      const char* data() const
      {
         return data_;
      }

      char* data()
      {
         return data_;
      }

      const unsigned char* header() const
      {
         return header_;
      }

      unsigned char* header()
      {
         return header_;
      }

      uint32_t length() const
      {
         return header_length + body_length_;
      }

      const char* body() const
      {
         return data_ + header_length;
      }

      char* body()
      {
         return data_ + header_length;
      }

      uint32_t body_length() const
      {
         return body_length_;
      }

      uint32_t channel() const
      {
         return channel_;
      }

      void channel(uint32_t channel)
      {
         channel_ = channel;
      }

      void body(const char* bodyBuffer, int len);
      void body_length(uint32_t length);
      void create_data_buffer();
      void decode_header();
      void encode_header();

   private:
      unsigned char header_[header_length];
      char* data_;
      uint32_t channel_;
      uint32_t body_length_;
   };

}

